/*
 * comm_entry.cpp
 *
 *  Created on: 2010-1-7
 *      Author: gavinkwoe
 */

#include "comm_objbase.h"
#include "cx_DownloadObserver.h"

/*************************************************************************
* GUID
*************************************************************************/

COMM_DEFINED_GUID( IComm_cx_DownLoadObserver, 1, "E374239D-ADFA-4d10-A446-BDDFC26C6E0F" )

/*************************************************************************
* STRUCTURE
*************************************************************************/

struct __struct_comm_download_Observer_data;
typedef struct __struct_comm_download_Observer_data		comm_download_Observer_data_t;
typedef struct __struct_comm_download_Observer_data *	comm_download_Observer_data_ptr_t;

/*************************************************************************
* DEFINITION
*************************************************************************/

struct __struct_comm_download_Observer_data
{
	unsigned long		        ref_cnt;	// reference count
	comm_obsvr_fptr_download_t	ntf_hdlr;
	comm_obsvr_fptr_download_t	ntf_downhdlr;
	comm_obsvr_fptr_download_t ntf_updatehdlr;
	comm_obsvr_fptr_download_t	ntf_storehdlr;
	unsigned long		        has_ud;	
	void *				        user_data;
};

/*************************************************************************
* LOCAL FUNCTIONS
*************************************************************************/

//const unsigned long	__CDownload_Observer_Construct( COMM_REF(ICommO) thiz, void * usr_data );
unsigned long	__CDownload_Observer_Destruct( COMM_REF(ICommO) thiz );
unsigned long	__CDownload_Observer_AddRef( COMM_REF(ICommO) thiz );
unsigned long	__CDownload_Observer_Release( COMM_REF(ICommO) thiz );

unsigned long	__CDownload_Observer_GetUserData( COMM_REF(ICommO) thiz, void ** pusr_data );
unsigned long	__CDownload_Observer_SetUserData( COMM_REF(ICommO) thiz, void * usr_data );
unsigned long	__CDownload_Observer_SetCallback( COMM_REF(ICommO) thiz, comm_obsvr_fptr_download_t hdlr );
unsigned long	__CDownload_Observer_SendNotify( COMM_REF(ICommO) thiz, int ntf_status, void * ntf_data );

unsigned long	__CDownload_SetDownloadCallback( COMM_REF(ICommO) thiz, IN comm_obsvr_fptr_download_t hdlr );
unsigned long	__CDownload_SendDownloadNotify( COMM_REF(ICommO) thiz, IN int ntf_status, IN void * ntf_data );

unsigned long	__CDownload_SetStoreCallback( COMM_REF(ICommO) thiz, IN comm_obsvr_fptr_download_t hdlr );
unsigned long	__CDownload_SendStoreNotify( COMM_REF(ICommO) thiz, IN int ntf_status, IN void * ntf_data );

/*************************************************************************
* IMPLEMENTATION
*************************************************************************/

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
const unsigned long __CDownload_Observer_Construct( COMM_REF(ICommO) thiz, void * usr_data )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	COMM_UNUSED( usr_data );
	
	if ( NULL == obj_data )
		return COMM_FAILED;

	obj_data->ref_cnt	= 1;
	obj_data->ntf_hdlr	= NULL;
	obj_data->ntf_downhdlr	= NULL;
	obj_data->ntf_updatehdlr = NULL;
	obj_data->ntf_storehdlr = NULL;	
	obj_data->has_ud	= COMM_FALSE;
	obj_data->user_data	= NULL;

	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __CDownload_Observer_Destruct( COMM_REF(ICommO) thiz )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __CDownload_Observer_AddRef( COMM_REF(ICommO) thiz )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;
	
	obj_data->ref_cnt++;
	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __CDownload_Observer_Release( COMM_REF(ICommO) thiz )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;
	
	obj_data->ref_cnt -= 1;

	if ( 0 == obj_data->ref_cnt )
	{
		comm_obj_delete( (void *)thiz );
	}
	
	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __CDownload_Observer_GetUserData( COMM_REF(ICommO) thiz, void ** pusr_data )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data || NULL == pusr_data )
		return COMM_FAILED;
	
	if ( COMM_FALSE == obj_data->has_ud )
		return COMM_FAILED;
	
	*pusr_data = obj_data->user_data;
	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __CDownload_Observer_SetUserData( COMM_REF(ICommO) thiz, void * usr_data )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;
	
	obj_data->has_ud	= COMM_TRUE;
	obj_data->user_data	= usr_data;
	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __CDownload_Observer_SetCallback( COMM_REF(ICommO) thiz, comm_obsvr_fptr_download_t hdlr )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;
	
	obj_data->ntf_hdlr = hdlr;
	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
unsigned long __CDownload_Observer_SendNotify( COMM_REF(ICommO) thiz, int ntf_status, void * ntf_data )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;
	
	if ( NULL != obj_data->ntf_hdlr )
	{
		COMM_INVOKE( obj_data->ntf_hdlr, ( thiz, ntf_status, ntf_data ) );
	}
	
	return COMM_OK;
}

unsigned long	__CDownload_SetDownloadCallback( COMM_REF(ICommO) thiz, IN comm_obsvr_fptr_download_t hdlr )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	obj_data->ntf_downhdlr = hdlr;
	return COMM_OK;
}

unsigned long	__CDownload_SendDownloadNotify( COMM_REF(ICommO) thiz, IN int ntf_status, IN void * ntf_data )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL != obj_data->ntf_downhdlr )
	{
		COMM_INVOKE( obj_data->ntf_downhdlr, ( thiz, ntf_status, ntf_data ) );
	}

	return COMM_OK;
}

static unsigned long	__CDownload_SetUpdateCallback( COMM_REF(ICommO) thiz, IN comm_obsvr_fptr_download_t hdlr )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	obj_data->ntf_updatehdlr = hdlr;
	return COMM_OK;
}

static unsigned long	__CDownload_SendUpdateNotify( COMM_REF(ICommO) thiz, IN int ntf_status, IN void * ntf_data )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL != obj_data->ntf_updatehdlr )
	{
		COMM_INVOKE( obj_data->ntf_updatehdlr, ( thiz, ntf_status, ntf_data ) );
	}

	return COMM_OK;
}


unsigned long	__CDownload_SetStoreCallback( COMM_REF(ICommO) thiz, IN comm_obsvr_fptr_download_t hdlr )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	obj_data->ntf_storehdlr = hdlr;
	return COMM_OK;
}

unsigned long	__CDownload_SendStoreNotify( COMM_REF(ICommO) thiz, IN int ntf_status, IN void * ntf_data )
{
	comm_download_Observer_data_ptr_t obj_data = (comm_download_Observer_data_ptr_t)COMM_GET_DATA( thiz );

	if ( NULL == obj_data )
		return COMM_FAILED;

	if ( NULL != obj_data->ntf_storehdlr )
	{
		COMM_INVOKE( obj_data->ntf_storehdlr, ( thiz, ntf_status, ntf_data ) );
	}

	return COMM_OK;
}

/*************************************************************************
* DESCRIPTION
*	$$__FUNC_DESC__$$
*************************************************************************/
COMM_EXPORT COMM_REF(ICommO) comm_cx_create_download_observer( void * reserved )
{
	//static const 
// 	const void * const __coclass_vtbl[10] =
// 	{
// 		// ICommO
// 		(void *)__CDownload_Observer_Construct,
// 		(void *)__CDownload_Observer_Destruct,
// 		(void *)__CDownload_Observer_AddRef,
// 		(void *)__CDownload_Observer_Release,
// 
// 		(void *)__CDownload_Observer_GetUserData,
// 		(void *)__CDownload_Observer_SetUserData,
// 		(void *)__CDownload_Observer_SetCallback,
// 		(void *)__CDownload_Observer_SendNotify,
// 		(void *)__CDownload_SetDownloadCallback,
// 		(void *)__CDownload_SendDownloadNotify
// 	};
	comm_coclass_desc_t __coclass_desc;
	void * __coclass_vtbl[14];
	int i=0;
	__coclass_vtbl[i++] =(void *)__CDownload_Observer_Construct;
	__coclass_vtbl[i++] =(void *)__CDownload_Observer_Destruct;
	__coclass_vtbl[i++] =(void *)__CDownload_Observer_AddRef;
	__coclass_vtbl[i++] =(void *)__CDownload_Observer_Release;
	__coclass_vtbl[i++] =(void *)__CDownload_Observer_GetUserData;
	__coclass_vtbl[i++] =(void *)__CDownload_Observer_SetUserData;
	__coclass_vtbl[i++] =(void *)__CDownload_Observer_SetCallback;
	__coclass_vtbl[i++] =(void *)__CDownload_Observer_SendNotify;
	__coclass_vtbl[i++] =(void *)__CDownload_SetDownloadCallback;
	__coclass_vtbl[i++] =(void *)__CDownload_SendDownloadNotify;
	__coclass_vtbl[i++] =(void *)__CDownload_SetUpdateCallback;
	__coclass_vtbl[i++] =(void *)__CDownload_SendUpdateNotify;
	__coclass_vtbl[i++] =(void *)__CDownload_SetStoreCallback;
	__coclass_vtbl[i++] =(void *)__CDownload_SendStoreNotify;	

// 	static const comm_coclass_desc_t __coclass_desc =
// 	{
// 		(unsigned char *)__coclass_vtbl,
// 		(unsigned long)sizeof( comm_download_Observer_data_t )
// 	};
		
		__coclass_desc.vtbl_size	= (unsigned long)sizeof(__coclass_vtbl);
		__coclass_desc.vtbl_funcs	= (unsigned char *)__coclass_vtbl;
		__coclass_desc.priv_size	= (unsigned long)sizeof(comm_download_Observer_data_t);
		


	return ( COMM_REF(ICommO) )comm_obj_new( (comm_coclass_desc_ptr_t)&__coclass_desc, reserved );
}
